"""程序入口"""

import os

import aiomysql
import aioredis
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.web import url  # URLSpec
from decouple import config
from tornado.options import define, options

from config import (
    DB_HOST, DB_PORT, DB_NAME, DEBUG,
    LOGGING_LEVEL,
    COOKIE_SECRET
)
from handlers.auth import (
    RegisterHandler,
    RegisterConfirmHandler,
    SendActivationEmailHandler,
    LoginHandler, LogoutHandler, PasswordResetHandler, PasswordResetConfirmHandler, PasswordChangeHandler,
)
from handlers.index import IndexHandler

define('port', default=6000, type=int, help='服务器端口')


async def create_mysql_pool():
    return await aiomysql.create_pool(
        host=DB_HOST,
        port=DB_PORT,
        user=config('DB_USER', default='root'),
        password=config('DB_PASSWORD', default='root'),
        db=DB_NAME,
        autocommit=False,
    )


# https://aioredis.readthedocs.io/en/v1.3.0/examples.html
async def create_redis_pool():
    return await aioredis.create_pool(
        'redis://localhost:6379/0?encoding=utf-8',
        minsize=5,
        maxsize=10,
    )


def make_app(settings):
    return tornado.web.Application([
        # 使用URLSpec对象给URL命名，在RequestHandler对象中可以使用reverse_url方法，反向生成URL
        url(r'/api/v1/', IndexHandler, name='index'),

        # auth
        url(r'/api/v1/auth/register/', RegisterHandler, name='auth_register'),
        url(r'/api/v1/auth/register/confirm/(\w+)/', RegisterConfirmHandler, name='auth_register_confirm'),
        url(r'/api/v1/auth/register/activate/', SendActivationEmailHandler, name='auth_send_activation_email'),
        url(r'/api/v1/auth/login/', LoginHandler, name='auth_login'),
        url(r'/api/v1/auth/logout/', LogoutHandler, name='auth_logout'),
        url(r'/api/v1/auth/password/reset/', PasswordResetHandler, name='auth_password_reset'),
        url(r'/api/v1/auth/password/reset/confirm/(\w+)/', PasswordResetConfirmHandler, name='auth_password_reset_confirm'),
        url(r'/api/v1/auth/password/change/', PasswordChangeHandler, name='auth_password_change'),
    ], **settings)


def main():
    options.log_file_prefix = os.path.join(os.path.dirname(__file__), 'logs/log')
    options.logging = LOGGING_LEVEL  # 'DEBUG' in development
    tornado.options.parse_command_line()

    ioloop = tornado.ioloop.IOLoop.current()
    mysql_pool = ioloop.run_sync(create_mysql_pool)
    redis_pool = ioloop.run_sync(create_redis_pool)

    app = make_app({
        'debug': DEBUG,
        'mysql_pool': mysql_pool,
        'redis_pool': redis_pool,
        'cookie_secret': COOKIE_SECRET,
        'login_url': '/api/v1/auth/login/'  # 使用tornado.web.authenticated装饰器必须定义login_url
    })
    app.listen(options.port)
    ioloop.start()


if __name__ == '__main__':
    import sys

    sys.stderr.write(f'服务器启动于:{options.port}')
    main()
